// BrowserSink.h: interface for the CBrowserSink class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_BROWSERSINK_H__7F9C8A3E_9F93_43C4_AD25_FF0DBD59ED71__INCLUDED_)
#define AFX_BROWSERSINK_H__7F9C8A3E_9F93_43C4_AD25_FF0DBD59ED71__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <vector>
#include <ocidl.h> // IDispatch
#include <exdisp.h>
#include <mshtml.h>	

//--------------------------------------------------------------------------
// forword decalretion
//--------------------------------------------------------------------------
class IBrowserEventListener;
class IHtmlDocEventListener;
class IHtmlWndEventListener;

class IBrowserEventListener
{
public:
	virtual ~IBrowserEventListener() {}

	virtual void OnTitleChange(IDispatch *pSinkThis, BSTR title) = 0;
	virtual void OnPreNavigate(IDispatch *pSinkThis) = 0;
	virtual void OnDocumentComplete(IDispatch *pSinkThis, IDispatch *pWebBrowser2, BSTR pszUrl) = 0;
	virtual void OnOtherEvent(IDispatch *pSinkThis, DISPID dispIdMember, DISPPARAMS *pDispParams, VARIANT *pVarResult) = 0;
};

class IHtmlDocEventListener
{
public:
	virtual ~IHtmlDocEventListener(){}
};

class IHtmlWndEventListener
{
public:
	virtual ~IHtmlWndEventListener(){}

	virtual void OnHtmlWndScroll(IDispatch *pSinkThis) = 0;
};


//--------------------------------------------------------------------------
// CDispatchImpl
//--------------------------------------------------------------------------
class CDispatchImpl : public IDispatch  
{
public:
	CDispatchImpl();
	virtual ~CDispatchImpl();

public:
	// IUnknown
	virtual HRESULT STDMETHODCALLTYPE QueryInterface( 
        /* [in] */ REFIID riid,
        /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);

    virtual ULONG STDMETHODCALLTYPE AddRef( void) ;

    virtual ULONG STDMETHODCALLTYPE Release( void);

	// IDispatch
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( 
        /* [out] */  UINT *pctinfo);
    
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( 
        /* [in] */ UINT iTInfo,
        /* [in] */ LCID lcid,
        /* [out] */ ITypeInfo **ppTInfo);
    
    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
        /* [in] */  REFIID riid,
        /* [size_is][in] */ LPOLESTR *rgszNames,
        /* [range][in] */  UINT cNames,
        /* [in] */ LCID lcid,
        /* [size_is][out] */ DISPID *rgDispId);
    
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
        /* [in] */ DISPID dispIdMember,
        /* [in] */ REFIID riid,
        /* [in] */ LCID lcid,
        /* [in] */ WORD wFlags,
        /* [out][in] */ DISPPARAMS *pDispParams,
        /* [out] */ VARIANT *pVarResult,
        /* [out] */ EXCEPINFO *pExcepInfo,
        /* [out] */ UINT *puArgErr);
};


//--------------------------------------------------------------------------
// CEventSinkBase
//--------------------------------------------------------------------------
template<class Listener, class Source, const IID *pDIID>
class CEventSinkBase : public CDispatchImpl
{
public:
	typedef std::vector<Listener*>		LISTENER;
	typedef typename LISTENER::iterator LISTENER_ITER;

	typedef std::vector<Source *>			WEBBROWSER;
	typedef typename WEBBROWSER::iterator	WEBBROWSER_ITER;

	typedef std::vector<DWORD>				COOKIE;
	typedef std::vector<DWORD>::iterator	COOKIE_ITER;

public:
	bool Connect(Listener* pListener, Source *pWeb);
	bool Disconnect(Listener* pListener);
	
protected:
	LISTENER	m_vBrowserEventLister;
	WEBBROWSER	m_vBrowser;
	COOKIE		m_vCookie;
};



//--------------------------------------------------------------------------
// CBrowserEventSink(DWebBrowserEvents2)
//--------------------------------------------------------------------------

//template class CEventSinkBase<IBrowserEventListener, IWebBrowser2, &DIID_DWebBrowserEvents2>;
typedef CEventSinkBase<IBrowserEventListener, IWebBrowser2, &DIID_DWebBrowserEvents2> WebBrowserEventsBase;

class CBrowserEventSink : public WebBrowserEventsBase
//class CBrowserEventSink : public CDispatchImpl
{
public:
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
        /* [in] */ DISPID dispIdMember,
        /* [in] */ REFIID riid,
        /* [in] */ LCID lcid,
        /* [in] */ WORD wFlags,
        /* [out][in] */ DISPPARAMS *pDispParams,
        /* [out] */ VARIANT *pVarResult,
        /* [out] */ EXCEPINFO *pExcepInfo,
        /* [out] */ UINT *puArgErr);
};


//--------------------------------------------------------------------------
// CHtmlWindowEventSink(HTMLWindowEvents2, DIID_HTMLWindowEvents2) DISPID_HTMLWINDOWEVENTS2_ONSCROLL;
//--------------------------------------------------------------------------
typedef CEventSinkBase<IHtmlWndEventListener, IHTMLWindow2, &DIID_HTMLWindowEvents2> HtmlWindowEventBase;

class CHtmlWindowEventSink : public HtmlWindowEventBase
{
public:
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
        /* [in] */ DISPID dispIdMember,
        /* [in] */ REFIID riid,
        /* [in] */ LCID lcid,
        /* [in] */ WORD wFlags,
        /* [out][in] */ DISPPARAMS *pDispParams,
        /* [out] */ VARIANT *pVarResult,
        /* [out] */ EXCEPINFO *pExcepInfo,
        /* [out] */ UINT *puArgErr);
};					


//--------------------------------------------------------------------------
// CHtmlDocumentEventSink(HTMLDocumentEvents2, DIID_HTMLDocumentEvents2) DISPID_HTMLDOCUMENTEVENTS2_ONACTIVATE;
//--------------------------------------------------------------------------
typedef CEventSinkBase<IHtmlDocEventListener, IHTMLDocument2, &DIID_HTMLDocumentEvents2> HtmlDocumentEventsBase;

class CHtmlDocumentEventSink : public HtmlDocumentEventsBase
{
public:
    virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
        /* [in] */ DISPID dispIdMember,
        /* [in] */ REFIID riid,
        /* [in] */ LCID lcid,
        /* [in] */ WORD wFlags,
        /* [out][in] */ DISPPARAMS *pDispParams,
        /* [out] */ VARIANT *pVarResult,
        /* [out] */ EXCEPINFO *pExcepInfo,
        /* [out] */ UINT *puArgErr);
};

#endif // !defined(AFX_BROWSERSINK_H__7F9C8A3E_9F93_43C4_AD25_FF0DBD59ED71__INCLUDED_)
